package com.ty.service.impl;

import com.ty.bean.Express;
import com.ty.dao.BaseExpressDao;
import com.ty.dao.impl.BaseExpressDaoImpl;
import com.ty.exception.DuplicateCodeException;
import com.ty.service.BaseExpressService;
import com.ty.util.RandomUtil;
import com.ty.util.SMSUtil;
import com.ty.util.UserUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 田野
 */
public class BaseExpressServiceImpl implements BaseExpressService {

    private BaseExpressDao expressDao = new BaseExpressDaoImpl();

    /**
     * 用于查询数据库中的全部快递(总数+新增) 代取件快递(总数+新增)
     *
     * @return [{size:总数, day:新增},{size:总数, day:新增}]
     */
    @Override
    public List<Map<String, Integer>> console() {
        List<Integer> console = expressDao.console();

        List<Map<String, Integer>> data = new ArrayList<>();

        if (console != null && console.size() > 0){
            Map<String, Integer> data1 = Map.of("data1_size", console.get(0), "data1_day", console.get(1));
            Map<String, Integer> data2 = Map.of("data2_size", console.get(2), "data2_day", console.get(3));
            data.add(data1);
            data.add(data2);
        }
        return data;
    }

    /**
     * 用于分页查询数据库中的所有快递信息
     *
     * @param limit      true表示开启分页查询(默认) false 表示查询所有快递
     * @param offset     表示 SQL 语句起始索引
     * @param pageNumber 表示页查询快递数量
     * @return List<Express> 快递集合
     */
    @Override
    public List<Express> findAll(boolean limit, int offset, int pageNumber) {
        List<Express> all = expressDao.findAll(limit, offset, pageNumber);
        return all;
    }

    /**
     * 根据快递运单号查询快递信息
     *
     * @param number 快递单号
     * @return Express 单号不存在时返回 null
     */
    @Override
    public Express findByNumber(String number) {
        Express byNumber = expressDao.findByNumber(number);
        return byNumber;
    }

    /**
     * 根据快递取件码查询快递信息
     *
     * @param code 快递取件码
     * @return Express 取件码不存在时返回 null
     */
    @Override
    public Express findByCode(String code) {
        Express byCode = expressDao.findByCode(code);
        return byCode;
    }

    /**
     * 根据手机号码查询所有的快递信息
     *
     * @param userPhone 手机号码
     * @param status    快递状态 0表示查询代取件的快递(默认) 1表示查询已取件的快递 2 表示查询用户的所有快递
     * @return List<Express>
     */
    @Override
    public List<Express> findByUserPhone(String userPhone, int status) {
        List<Express> byUserPhone = expressDao.findByUserPhone(userPhone, status);
        return byUserPhone;
    }

    /**
     * 根据录入人的手机号，查询快递信息
     *
     * @param sysPhone 录入人的手机号码
     * @return List<Express>
     */
    @Override
    public List<Express> findBySysPhone(String sysPhone) {
        List<Express> bySysPhone = expressDao.findBySysPhone(sysPhone);
        return bySysPhone;
    }

    /**
     * 根据姓名，进行模糊查询快递总数
     *
     * @param username 用户姓名
     * @return Integer
     */
    @Override
    public Integer findByUsername(String username) {
        Integer byUsername = expressDao.findByUsername(username);
        return byUsername;
    }

    /**
     * 快件录入
     *
     * @param express 快递对象
     * @return true表示录入成功  false表示录入失败
     *
     * 通过递归解决取件码重复问题
     */
    @Override
    public boolean insert(Express express) {
        // 生成取件码
        String code = RandomUtil.getCode();
        express.setCode(code);

        try {
            boolean insert = expressDao.insert(express);

            // TODO:这一个环节很重要，快递入柜之后给用户发短信，后面再完成
            // TODO:假装是已经发送了，因为阿里云的短信服务好像审核有问题
            //  必须得网站搭建之后才能申请。
            /*if (insert){
                // 录入成功就给收件人发送短信
                SMSUtil.send(express.getUserPhone(), express.getCode());
            }*/

            return insert;
        } catch (DuplicateCodeException e) {
            return insert(express);
        }
    }

    /**
     * 修改快递信息
     * String number,
     * String company,
     * String username,
     * String userPhone,
     * int status
     *
     * @param id         要修改的快递id
     * @param newExpress 新的快递对象
     * @return true 表示修改成功 false 表示修改失败
     */
    @Override
    public boolean update(int id, Express newExpress) {
        boolean update = false;
        boolean updateStatus = false;
        if (newExpress.getUserPhone() != null){
            expressDao.delete(id);
            return insert(newExpress);
        }else {

            // 在dao中增加一个findById的方法就能避免未更改手机的用户的手机号码在修改的时候为空
            Express byId = expressDao.findById(id);
            newExpress.setUserPhone(byId.getUserPhone());
            // 非原子性操作
            update = expressDao.update(id, newExpress);
            Express byNumber = expressDao.findByNumber(newExpress.getNumber());
            if (newExpress.getStatus() == 1){
                updateStatus = updateStatus(byNumber.getNumber());
            }
            // 只有当两条语句都执行成功的时候，才返回true
            if (update && updateStatus){
                return true;
            }else {
                if (!update){
                    expressDao.update(id, byId);
                }

                return false;
            }

        }
    }

    /**
     * 根据快递id删除快递信息
     *
     * @param id 要删除的快递id
     * @return true表示删除成功 false 表示删除失败
     */
    @Override
    public boolean delete(int id) {
        boolean delete = expressDao.delete(id);
        return delete;
    }

    /**
     * 确认取件
     *
     * @param number 要更改为已取件的快递单号
     * @return true表示已成功取件 false 表示取件失败
     */
    @Override
    public boolean updateStatus(String number) {
        boolean b = expressDao.updateStatus(number);
        return b;
    }
}
